/**
 * +----------------------------------------------------------------------------------------------+
 * |Date               |  Version  |Author             |Description                              |
 * |==========+=======+==============+===================|
 * |2018年9月13日     |  1.0.0       | kreo                 |Initial                                       |
 * +----------------------------------------------------------------------------------------------+
 */
package main.java.utils.hxy.thread.thread;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.*;

/**
 * 单线程线程池工厂类, 特点是根据Key去取得线程池,而每个Key的线程池是个单线程池
 *
 * @ClassName ISinglePoolFactory
 * @Description
 */
public class ISinglePoolFactory {
    // private final static Logger log = Logger.getLogger(ISinglePoolFactory.class);
    private final static String DEFAULT_KEY = "DEFAULT";
    private static Map<String, ThreadPoolExecutor> services = new HashMap<>();

    public static Set<String> getServiceNames() {
        return services.keySet();
    }

    /**
     * 得到一个线程池
     * 2018年9月13日 下午10:15:08
     *
     * @param key
     * @return
     * @Author kreo
     */
    public static ThreadPoolExecutor getPool(String key) {
        ThreadPoolExecutor executor = null;
        if (services.containsKey(key)) {
            executor = services.get(key);
        }
        if (executor == null) {
            executor = new ThreadPoolExecutor(1, 1,
                    0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<Runnable>());
            services.put(key, executor);
        }
        return executor;
    }

    /**
     * 2018年9月13日 下午9:42:35
     *
     * @return
     * @Author kreo
     */
    public static ThreadPoolExecutor getPool() {
        return getPool(DEFAULT_KEY);
    }

    public static void addTask(String key, Runnable task) {
        getPool(key).execute(task);
    }

    /**
     * 在DEFAULT_KEY中添加一条任务
     * 2018年9月13日 下午10:03:37
     *
     * @param task
     * @Author kreo
     */
    public static void addTask(Runnable task) {
        addTask(DEFAULT_KEY, task);
    }

    /**
     * 在DEFAULT_KEY中添加一条Future
     * 2018年2月6日 下午2:11:41
     *
     * @return
     */
    public static <T> Future<T> addCallable(String key, Callable<T> callable) {
        return getPool(key).submit(callable);
    }

    public static <T> Future<T> addCallable(Callable<T> callable) {
        return addCallable(DEFAULT_KEY, callable);
    }

    public static void shutdown(String key) {
        if (services.containsKey(key)) {
            IPool.shutdown(services.get(key));
            services.remove(key);
        }
    }

    public static void shutdown() {
        for (Entry<String, ThreadPoolExecutor> serviceEntry : services.entrySet()) {
            serviceEntry.getValue().shutdown();
        }
        services.clear();
    }
}
